/**
 * 缓存管理器 - 用于管理TLE数据和地图瓦片的本地缓存
 * 支持localStorage和IndexedDB两种存储方式
 */

class CacheManager {
	constructor() {
		this.dbName = 'SatelliteTrackDB';
		this.dbVersion = 1;
		this.tleStoreName = 'tleData';
		this.mapTileStoreName = 'mapTiles';
		this.db = null;
		this.initDB();
	}

	/**
	 * 初始化IndexedDB数据库
	 */
	async initDB() {
		return new Promise((resolve, reject) => {
			const request = indexedDB.open(this.dbName, this.dbVersion);

			request.onerror = () => {
				console.error('IndexedDB打开失败:', request.error);
				reject(request.error);
			};

			request.onsuccess = () => {
				this.db = request.result;
				console.log('IndexedDB初始化成功');
				resolve(this.db);
			};

			request.onupgradeneeded = (event) => {
				const db = event.target.result;

				// 创建TLE数据存储对象仓库
				if (!db.objectStoreNames.contains(this.tleStoreName)) {
					const tleStore = db.createObjectStore(this.tleStoreName, {
						keyPath: 'id'
					});
					tleStore.createIndex('group', 'group', { unique: false });
					tleStore.createIndex('timestamp', 'timestamp', { unique: false });
				}

				// 创建地图瓦片存储对象仓库
				if (!db.objectStoreNames.contains(this.mapTileStoreName)) {
					const mapStore = db.createObjectStore(this.mapTileStoreName, {
						keyPath: 'url'
					});
					mapStore.createIndex('timestamp', 'timestamp', { unique: false });
				}
			};
		});
	}

	/**
	 * 保存TLE数据到本地
	 * @param {string} group - 卫星组名称
	 * @param {string} data - TLE数据
	 * @param {boolean} useIndexedDB - 是否使用IndexedDB存储
	 */
	async saveTleData(group, data, useIndexedDB = true) {
		const timestamp = Date.now();
		const tleRecord = {
			id: group,
			group: group,
			data: data,
			timestamp: timestamp,
			size: new Blob([data]).size
		};

		if (useIndexedDB && this.db) {
			try {
				const transaction = this.db.transaction([this.tleStoreName], 'readwrite');
				const store = transaction.objectStore(this.tleStoreName);
				await new Promise((resolve, reject) => {
					const request = store.put(tleRecord);
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});
				console.log(`TLE数据已保存到IndexedDB: ${group}`);
			} catch (error) {
				console.error('保存TLE数据到IndexedDB失败:', error);
				// 降级到localStorage
				this.saveTleToLocalStorage(group, tleRecord);
			}
		} else {
			this.saveTleToLocalStorage(group, tleRecord);
		}
	}

	/**
	 * 保存TLE数据到localStorage
	 */
	saveTleToLocalStorage(group, tleRecord) {
		try {
			const key = `tle_${group}`;
			localStorage.setItem(key, JSON.stringify(tleRecord));
			console.log(`TLE数据已保存到localStorage: ${group}`);
		} catch (error) {
			console.error('保存TLE数据到localStorage失败:', error);
		}
	}

	/**
	 * 从本地获取TLE数据
	 * @param {string} group - 卫星组名称
	 * @param {boolean} useIndexedDB - 是否优先使用IndexedDB
	 * @returns {Object|null} TLE数据记录
	 */
	async getTleData(group, useIndexedDB = true) {
		if (useIndexedDB && this.db) {
			try {
				const transaction = this.db.transaction([this.tleStoreName], 'readonly');
				const store = transaction.objectStore(this.tleStoreName);
				const result = await new Promise((resolve, reject) => {
					const request = store.get(group);
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});
				if (result) {
					console.log(`从IndexedDB获取TLE数据: ${group}`);
					return result;
				}
			} catch (error) {
				console.error('从IndexedDB获取TLE数据失败:', error);
			}
		}

		// 降级到localStorage
		return this.getTleFromLocalStorage(group);
	}

	/**
	 * 从localStorage获取TLE数据
	 */
	getTleFromLocalStorage(group) {
		try {
			const key = `tle_${group}`;
			const data = localStorage.getItem(key);
			if (data) {
				const result = JSON.parse(data);
				console.log(`从localStorage获取TLE数据: ${group}`);
				return result;
			}
		} catch (error) {
			console.error('从localStorage获取TLE数据失败:', error);
		}
		return null;
	}

	/**
	 * 检查TLE数据是否过期
	 * @param {Object} tleRecord - TLE数据记录
	 * @param {number} maxAge - 最大缓存时间（毫秒），默认24小时
	 * @returns {boolean} 是否过期
	 */
	isTleDataExpired(tleRecord, maxAge = 24 * 60 * 60 * 1000) {
		if (!tleRecord || !tleRecord.timestamp) {
			return true;
		}
		return Date.now() - tleRecord.timestamp > maxAge;
	}

	/**
	 * 获取所有已缓存的TLE数据组
	 * @returns {Array} 缓存的组列表
	 */
	async getAllCachedTleGroups() {
		const groups = [];

		if (this.db) {
			try {
				const transaction = this.db.transaction([this.tleStoreName], 'readonly');
				const store = transaction.objectStore(this.tleStoreName);
				const result = await new Promise((resolve, reject) => {
					const request = store.getAllKeys();
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});
				groups.push(...result);
			} catch (error) {
				console.error('获取IndexedDB缓存组失败:', error);
			}
		}

		// 同时检查localStorage
		for (let i = 0; i < localStorage.length; i++) {
			const key = localStorage.key(i);
			if (key && key.startsWith('tle_')) {
				const group = key.replace('tle_', '');
				if (!groups.includes(group)) {
					groups.push(group);
				}
			}
		}

		return groups;
	}

	/**
	 * 删除指定组的TLE数据
	 * @param {string} group - 卫星组名称
	 */
	async deleteTleData(group) {
		if (this.db) {
			try {
				const transaction = this.db.transaction([this.tleStoreName], 'readwrite');
				const store = transaction.objectStore(this.tleStoreName);
				await new Promise((resolve, reject) => {
					const request = store.delete(group);
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});
			} catch (error) {
				console.error('删除IndexedDB中TLE数据失败:', error);
			}
		}

		// 同时删除localStorage中的数据
		try {
			localStorage.removeItem(`tle_${group}`);
		} catch (error) {
			console.error('删除localStorage中TLE数据失败:', error);
		}
	}

	/**
	 * 清空所有TLE缓存数据
	 */
	async clearAllTleData() {
		if (this.db) {
			try {
				const transaction = this.db.transaction([this.tleStoreName], 'readwrite');
				const store = transaction.objectStore(this.tleStoreName);
				await new Promise((resolve, reject) => {
					const request = store.clear();
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});
			} catch (error) {
				console.error('清空IndexedDB中TLE数据失败:', error);
			}
		}

		// 清空localStorage中的TLE数据
		const keysToRemove = [];
		for (let i = 0; i < localStorage.length; i++) {
			const key = localStorage.key(i);
			if (key && key.startsWith('tle_')) {
				keysToRemove.push(key);
			}
		}
		keysToRemove.forEach((key) => localStorage.removeItem(key));
	}

	/**
	 * 获取缓存统计信息
	 * @returns {Object} 缓存统计
	 */
	async getCacheStats() {
		const stats = {
			tleGroups: 0,
			totalSize: 0,
			oldestTimestamp: null,
			newestTimestamp: null
		};

		try {
			// 确保数据库已初始化
			await this.initDB();

			if (this.db) {
				const transaction = this.db.transaction([this.tleStoreName], 'readonly');
				const store = transaction.objectStore(this.tleStoreName);
				const records = await new Promise((resolve, reject) => {
					const request = store.getAll();
					request.onsuccess = () => resolve(request.result);
					request.onerror = () => reject(request.error);
				});

				stats.tleGroups = records.length;
				records.forEach((record) => {
					stats.totalSize += record.size || 0;
					if (!stats.oldestTimestamp || record.timestamp < stats.oldestTimestamp) {
						stats.oldestTimestamp = record.timestamp;
					}
					if (!stats.newestTimestamp || record.timestamp > stats.newestTimestamp) {
						stats.newestTimestamp = record.timestamp;
					}
				});
			}
		} catch (error) {
			console.error('获取缓存统计失败:', error);
		}

		return stats;
	}
}

// 创建单例实例
const cacheManager = new CacheManager();

export default cacheManager;
export { CacheManager };
